#!/bin/bash
# Author: Steven Shiau <steven _at_ clonezilla org>
# License: GPL

# Load functions
DRBL_SCRIPT_PATH="${DRBL_SCRIPT_PATH:-/usr/share/drbl}"
. $DRBL_SCRIPT_PATH/sbin/drbl-conf-functions
. /etc/drbl/drbl-ocs.conf
. $DRBL_SCRIPT_PATH/sbin/ocs-functions

# Settings
LIVE_MEDIA=""
# console_prefer_font is from drbl-ocs.conf
#
get_live_media_mnt_point

if [ -z "$LIVE_MEDIA" ]; then
  echo "///WARNING/// filesystem.squashfs not found! No idea where is LIVE_MEDIA!!!"
fi
echo "Live media is in $LIVE_MEDIA"

# Prepare drbl/clonezilla runtime programs and dir
if [ -e $LIVE_MEDIA/pkg/custom-ocs ]; then
  echo "Preparing customized Clonezilla program $DRBL_SCRIPT_PATH/sbin/custom-ocs..."
  install -m 755 $LIVE_MEDIA/pkg/custom-ocs $DRBL_SCRIPT_PATH/sbin/
fi

echo "Updating /etc/ocs/ocs-live.conf based on kernel parameters if found... "
# Get options from kernel parameter if available.
# A normal bootparam in /proc/cmdline for clonezilla live is like:
# initrd=initrd-pxe.img devfs=nomount drblthincli=off selinux=0 ip= ocs_live_run="ocs-live-general"
param_2_be_parsed="ocs_live_run ocs_live_extra_param ocs_live_keymap ocs_live_batch ocs_lang ocs_daemonon ocs_daemonoff ocs_numlk ocs_capslk ocs_live_run_tty ocs_batch_mode ocs_live_type ocsroot_src ocs_sr_save_extra_opt ocs_sr_restore_extra_opt ocs_fontface ocs_fontsize ocs_prompt_mode ocs_postmode_prompt ocs_dmesg_n ocs_ecryptfs_cipher ocs_ecryptfs_key_bytes ocs_sshd_port only_access_by_owner ocs_netlink_timeout ezio_seeder_ezio_leecher_opt ezio_common_opt secure_boot_client live_console_font_size"
parse_cmdline_option "$param_2_be_parsed"

# 2012/06/30 Give warning about ocs_lang and ocs_live_keymap are deprecated.
show_deprecated_ocs_lang_and_keymap

# Before writting these parameters to /etc/ocs/ocs-live.conf, first we deal with console parameter. The ocs_live_run_tty will be overwritten by console=.* boot parameter if console=.* is set.
# i.e. if live-getty and console=... (e.g. live-getty console=ttyS0,38400n81) are assigned in boot parameters, we make it as the default for ocs_live_run_tty.
# The priority for the boot parameters: (1) console=.* parameter (2) ocs_live_run_tty parameter
ocs_live_run_tty_set_in_cmdline=""
[ -n "$ocs_live_run_tty" ] && ocs_live_run_tty_set_in_cmdline="yes"
if [ -n "$(LC_ALL=C grep -iw live-getty /proc/cmdline)" -a \
     -n "$(LC_ALL=C grep -io "console=.*" /proc/cmdline)" ]; then
  # The following is borrowed from live-initramfs
  for ARGUMENT in $(cat /proc/cmdline); do
    case "${ARGUMENT}" in
      console=*) DEFCONSOLE="${ARGUMENT#*=}" ;;
    esac
  done
  ocs_live_run_tty="/dev/$(echo "${DEFCONSOLE}" | sed -e 's%,.*%%')"
  if [ "$ocs_live_run_tty_set_in_cmdline" = "yes" ]; then
    echo "//NOTE// Boot parameters live-getty and $DEFCONSOLE were found in /proc/cmdline! Make ocs_live_run_tty=$ocs_live_run_tty! The original assignment of ocs_live_run_tty in the boot parameter is ignored!"
    echo -n "Press \"Enter\" to continue..."
    read
  fi
fi

# 2012/06/28 ocs_lang should honor the parameter "locales" of live-config.
# 2012/06/29 live-config.keyboard-layouts=*|keyboard-layouts=* is from boot parameters of live-config. Here we only want to be compatible with live-config.keyboard-layouts or keyboard-layouts. Still let live-config to do the keyboard configuration. Then ocs_live_keymap should be deprecated.
for ARGUMENT in $(cat /proc/cmdline); do
  case "${ARGUMENT}" in
    live-config.locales=*|locales=*) 
	    ocs_lang="${ARGUMENT#*locales=}"
    	    ;;
    live-config.keyboard-layouts=*|keyboard-layouts=*)
    	    live_keyboard_layouts="${ARGUMENT#*keyboard-layouts=}"
    	    ;;
  esac
done

# Tune the param in /etc/ocs/ocs-live.conf
for ik in $param_2_be_parsed live_keyboard_layouts; do
  eval real_var=\$$ik
  if [ -n "$real_var" ]; then
    if [ -z "$(LANG=C grep -E "^[[:space:]]*$ik=" /etc/ocs/ocs-live.conf 2>/dev/null)" ]; then
      # append it
      echo "$ik=\"$real_var\"" >> /etc/ocs/ocs-live.conf
    else
      # modify it
      perl -pi -e "s|^[[:space:]]*$ik=.*|$ik=\"$real_var\"|g" /etc/ocs/ocs-live.conf
    fi
  fi
done
echo "done!"

# Forget about this. From Ubuntu Karmic, we use the /usr/share/initramfs-tools/scripts/init-top/framebuffer comes with initramfs-tools to deal with this. i.e. we use the format mode_option:<xres>x<yres>[-<bpp>][@<refresh>] in the boot parameter to start uvesafb. //NOTE// video=uvesafb:1024x768 won't work in Karmic. We have to use something like video=uvesafb:mode_option=1024x768. Ref: https://bugs.launchpad.net/ubuntu/+source/initramfs-tools/+bug/437871
# # Parse the cmdline then add options for uvesafb
# if LANG=C grep -q "mode_option=" /proc/cmdline; then
#   echo "Getting mode_option from kernel parameter... "
#   mode_option="$(LC_ALL=C grep -Ew mode_option /proc/cmdline | sed -e "s/.*mode_option=\([^ ]\+\).*$/\1/")"
#   if [ -n "$(LC_ALL=C lsmod | grep -Ew uvesafb)" ]; then
#     echo "Unloading uvesafb and load it again to make mode_option=\"$mode_option\" work... "
#     rmmod uvesafb
#     echo "done!"
#   fi
#   echo "Loading uvesafb module..."
#   modprobe uvesafb mode_option=$mode_option
# fi

# Load the config
[ -e "/etc/ocs/ocs-live.conf" ] && . /etc/ocs/ocs-live.conf

# Make sshd allow password to login. This was disabled by live-config (v4.x).
perl -pi -e 's|^[#]*[[:space:]]*(PasswordAuthentication) .*|$1 yes|' \
/etc/ssh/sshd_config

if [ -n "$ocs_sshd_port" ]; then
  perl -pi -e "s|^Port[[:space:]]+.*|Port $ocs_sshd_port|" /etc/ssh/sshd_config
fi

# Process the daemon on and off
for i in $ocs_daemonon; do
  # /etc/init.d/$i start
  drbl_service_ctl $i start
done

for i in $ocs_daemonoff; do
  # /etc/init.d/$i stop
  drbl_service_ctl $i stop
done

# Suppress dmesg on console if no ocs_dmesg_on
if [ -n "$ocs_dmesg_n" ]; then
  dmesg -n $ocs_dmesg_n
else
  # If not assigned, prevents all messages, except emergency (panic) messages
  dmesg -n 1
fi

if [ -e /dev/fb/0 -o -e /dev/fb0 ]; then 
  # Setup the console font. The setting is in /etc/default/console-setup
  # We'd like to make KMS font on the console larger, e.g.
  # FONTFACE="Terminus"
  # FONTSIZE="28x14"
  # From console-setup manual (5):
  # Valid font faces are: VGA (sizes  8x8,  8x14,  8x16,  16x28  and 16x32),  Terminus  (sizes  6x12, 8x14, 8x16, 10x20, 12x24, 14x28 and 16x32), TerminusBold (sizes 8x14, 8x16, 10x20, 12x24,  14x28 and  16x32),  TerminusBoldVGA  (sizes  8x14 and 8x16), and Fixed (sizes  8x13,  8x14,  8x15,  8x16   and   8x18). 
  # //NOTE// Only when KMS we will use this. Check /proc/fb
  # The content of /proc/fb
  # For vesafb:
  # 0 VESA VGA
  # For Intel DRM fb:
  # 0 inteldrmfb
  # For Nvidia fb:
  # 0 nouveaufb
  # For Radeon fb:
  # 0 radeondrmfb
  if [ -n "$(grep -Ew "(inteldrmfb|nouveaufb|radeondrmfb)" /proc/fb)" ]; then
    [ -z "$ocs_fontface" ] && ocs_fontface="$console_prefer_font"
    if [ -z "$ocs_fontsize" ] ; then
      get_best_console_font_size  # output is $console_font_size
      ocs_fontsize="$console_font_size"
    fi
    perl -pi -e "s|^FONTFACE=.*|FONTFACE=\"$ocs_fontface\"|g" /etc/default/console-setup
    perl -pi -e "s|^FONTSIZE=.*|FONTSIZE=\"$ocs_fontsize\"|g" /etc/default/console-setup
    # Make it work now
    setupcon
  fi
fi

# Process the number lock and capslock
case "$ocs_numlk" in
  on|ON) setleds +num ;;
  off|OFF) setleds -num ;;
esac
	
case "$ocs_capslk" in
  on|ON) setleds +caps;;
  off|OFF) setleds -caps ;;
esac

# Append start clonezilla in auto login account's (with sudo privilege) bash profile
get_live_autologin_account
if [ -z "$live_autologin_account" ]; then
   echo "No account with NOPASSWD sudo privilege was found!"
   echo "Program terminated!"
   exit 1
fi
get_live_auto_login_id_home
if [ -z "$(LANG=C grep -E "^[^#][[:space:]]*sudo -i ocs-live-run-menu" $live_auto_login_id_home/.bash_profile 2>/dev/null)" ]; then
  if [ -z "$(LC_ALL=C grep -iE "ocs_server" /proc/cmdline)" ]; then
    # If the job is from Clonezilla SE, i.e. ocs_server is found in /proc/cmdline, we won't put the "clear" command in auto account's ~/.bash_profile. It's easier to debug in verbose for Clonezilla-live based Clonezilla SE.
    cat <<-PROFILE_END >> $live_auto_login_id_home/.bash_profile
# Added by Clonezilla live
clear
PROFILE_END
  fi
  cat <<-PROFILE_END >> $live_auto_login_id_home/.bash_profile
# By default we will start clonezilla on /dev/tty1 (no more /dev/ttyS0) only when \$ocs_live_run_tty is not specivied. If you want to use ttyS0, add live-getty and console=ttyS0,38400n81 in the boot parameter. The control is inside ocs-live-run-menu.
if [ -e /run/lock/start-ocs-lang-kbd-conf ]; then
  sudo -i ocs-lang-kbd-conf
  sudo rm -f /run/lock/start-ocs-lang-kbd-conf
fi
if type ocs-live-run-menu &>/dev/null; then
 sudo -i ocs-live-run-menu
fi
PROFILE_END
  chown $live_autologin_account.$live_autologin_account $live_auto_login_id_home/.bash_profile
fi

# put username in /run/live/live-config
mkdir -p /run/live/
echo "LIVE_USERNAME=\"${live_autologin_account}\"" > /run/live/live-config

# ocs_live_keymap and ocs_lang will be processed later in another service

# Prepare mounting point for $ocsroot
[ -n "$ocsroot" ] && mkdir -p $ocsroot

# Tune the system for different arch
cpu_arch="$(LC_ALL=C uname -m)"
case $cpu_arch in
  i686|i386) 
	# Ref: https://sourceforge.net/p/clonezilla/discussion/Clonezilla_live/thread/ba31ffc8
	# http://stackoverflow.com/questions/30519417/why-linux-disables-disk-write-buffer-when-system-ram-is-greater-than-8gb
	# Linux kernel disables disk write buffer when system ram is greater than 8GB.
	ram_size_in_MB="$(LC_ALL=C vmstat -S M -s | grep -i "total memory" | awk -F" " '{print $1}')"
	if [ "$ram_size_in_MB" -ge 8192 ]; then
          echo 1 > /proc/sys/vm/highmem_is_dirtyable
        fi
        ;;
esac

# A workaround to make Ubuntu resolv.conf work for Ubuntu >= 18.04, only for live system.
# Maybe live-build can be patched for this in the future.
(
  [ -e /etc/lsb-release ] && . /etc/lsb-release
  if [ "$DISTRIB_ID" = "Ubuntu" ]; then
    cd /etc
    rm -f resolv.conf
    ln -fs ../run/systemd/resolve/stub-resolv.conf resolv.conf
  fi
)
